//! 数据格式

use crate::{Cmd, Kind, Status};
use alloc::vec::Vec;
use core::convert::TryInto;
use core::sync::atomic::{AtomicU16, Ordering};

static SN: AtomicU16 = AtomicU16::new(0);
pub fn set_sn(sn: u16) {
    SN.store(sn, Ordering::Relaxed);
}

/// 数据
#[derive(Debug)]
pub struct Data {
    /// 序列号
    sn: u16,
    /// 指令类别
    kind: Kind,
    /// 状态码
    status: Status,
    /// 消息体
    pub cmd: Cmd,
}
impl Data {
    pub fn new(kind: Kind, err: Status) -> Data {
        Data {
            sn: SN.fetch_add(1, Ordering::Relaxed),
            kind: kind,
            status: err,
            cmd: Cmd::default(),
        }
    }
    pub fn sn(&self) -> u16 {
        self.sn
    }
    pub fn set_sn(&mut self, sn: u16) {
        self.sn = sn
    }
    pub fn kind(&self) -> Kind {
        self.kind
    }
    pub fn status(&self) -> Status {
        self.status
    }
    pub fn set_status(&mut self, status: Status) {
        self.status = status;
    }
    pub fn cmd(&self) -> &Cmd {
        &self.cmd
    }
    pub fn set_cmd(&mut self, cmd: Cmd) {
        self.cmd = cmd;
    }
    pub fn parse(buf: &[u8]) -> Self {
        let sn = u16::from_be_bytes(buf[0..2].try_into().unwrap());
        let kind: Kind = buf[2].into();
        let status: Status = buf[3].into();
        let cmd: Cmd = Cmd::parse(kind, status, &buf[4..]);
        Data {
            sn,
            kind,
            status,
            cmd,
        }
    }
    pub fn to_buf(&self) -> Vec<u8> {
        let mut buf = Vec::from(self.sn.to_be_bytes());
        buf.push(self.kind as u8);
        buf.push(self.status as u8);
        buf.extend_from_slice(&self.cmd.to_buf());
        return buf;
    }
}
